
#include "include.h"

// variables
map<string, string> csv_data;
Result pricelist_config;
vector<int> service_mode;
vector<map<string, string>> service_mark_settings;

vector<vector<map<string, string>>> pricelist_tmp;
vector<map<string, string>> pricelist;
vector<string> prev_name;
vector<string> prev_field;
vector<string> prev_name_replaced;
vector<string> prev_field_replaced;
vector<bool> start_collecting_four;

vector<string> line_of_text;
map<string, string> csv;
// end variables



int toint(string val){
	return atoi(tochar(val));
}
string implode(string sep,vector<string> val){
	string result=val[0];
	for(int i=1;i<val.size();i++){
		result=result+sep+val[i];
	}
	return result;
}
char* tochar(string val){
	return (char*)val.c_str();
}
string alfanumericallowedonly(string str){
	string rgx = "[^A-Za-zА-Яа-я0-9]";
	wstring wrgx(rgx.begin(), rgx.end());
	boost::wregex r(wrgx.c_str());//(L"[^A-Za-zА-Яа-я0-9]");
	wstring newtext=L"";
	cout << "STRING: " << str << endl;
	wstring str1(str.begin(), str.end());
	wcout << L"STNG: " << str1.c_str() << endl;
	wstring str2(str1.c_str());
	wstring res =  boost::regex_replace(str2, r, newtext);
	wcout << L"WSTRING: " << str1 << endl;
	wcout << L"REPLACED: " << res << endl << endl;
	return string(res.begin(), res.end());
}
string p_replace(string reg,string newtext,string str){
	boost::regex r(reg);
	return boost::regex_replace(str, r, newtext);
}

vector<string> relative_reg(string reg,string input){
	vector<string> cmatch1;

	boost::regex r(reg);
	boost::smatch what;
	std::string::const_iterator start = input.begin();
	std::string::const_iterator end   = input.end();
	while (boost::regex_search(start, end, what, r))
	{
		string stest(what[1].first, what[1].second);
		cmatch1.push_back(stest);
		start = what[0].second;
	}
	return cmatch1;
}

string tolower(string data){
	string result = "";
	for(int i = 0; i< data.length(); i++) {
		if(data[i]<='Z' && data[i]>='A') {
			result += data[i] | 32;
		} else {
			result += data[i];
		}
	}
	return result;
}

string str_replace(string str2, string str3, string str1)
{
	while(true) {
		std::size_t found = str1.find(str2);
		if (found == std::string::npos)
			break;
		str1.replace(found, str2.length(), str3);
	}

	return str1;
}
vector <string> preg_match(string reg,string input){
	vector<string> cmatch1;
	boost::regex r("("+reg+")");
	boost::smatch what;
	std::string::const_iterator start = input.begin();
	std::string::const_iterator end   = input.end();
	while (boost::regex_search(start, end, what, r))
	{
		string stest(what[1].first, what[1].second);
		cmatch1.push_back(stest);
		start = what[0].second;
	}
	return cmatch1;
}
string prepare_price(string price){
	vector <string> matches;
	price=p_replace("[^0-9.,]","",price);
	matches=preg_match("(\\d+)",price);

	if(matches[0].length()==0){
		return 0;
	}
	string res="";
	int last_match=matches.size()-1;
	for(int i=0;i<=matches.size()-1;i++){
		if(last_match > 0 && i==last_match){
			res+="."+matches[i];
		}
		else{
			res+=matches[i];
		}
	}
	return res;
}


void processLine(string line)
{
	//cout << line << endl;
}

string relative_str(Result result,string col,string rel_col){
	if(col.length()<=0){
		trim(rel_col);
		regex reg(".+");
		vector<string> matches;
		matches=preg_match("[a-z]+|[+-]|[0-9]+",rel_col);
		if(matches.size() > 0){
			string column_start_from=matches[1];
			int step=atoi((char*)((string)matches[3]).c_str());
			string sign1=matches[2];
			char* sign=(char*)sign1.c_str();
			if(column_start_from.length()<=0)
				col=to_string(step);
			else{
				if(!strcmp("name",(char*)column_start_from.c_str())){
					if(result.columns.name.length()>0){
						if(!strcmp("+",sign))
							col=to_string(atoi((char*)result.columns.name.c_str()) + step);
						else if(!strcmp("-",sign))
							col=to_string(atoi((char*)result.columns.name.c_str()) - step);
					}
				}
				else if(!strcmp("code",(char*)column_start_from.c_str())){
					if(result.columns.code.length()>0){
						if(!strcmp("+",sign))
							col=to_string(atoi((char*)result.columns.code.c_str()) + step);
						else if(!strcmp("-",sign))
							col=to_string(atoi((char*)result.columns.code.c_str()) - step);
					}
				}
				else if(!strcmp("article",(char*)column_start_from.c_str())){
					if(result.columns.article.length()>0){
						if(!strcmp("+",sign))
							col=to_string(atoi((char*)result.columns.article.c_str()) + step);
						else if(!strcmp("-",sign))
							col=to_string(atoi((char*)result.columns.article.c_str()) - step);
					}
				}
				else if(!strcmp("price",(char*)column_start_from.c_str())){
					if(result.columns.price.length()>0){
						if(!strcmp("+",sign))
							col=to_string(atoi((char*)result.columns.price.c_str()) + step);
						else if(!strcmp("-",sign))
							col=to_string(atoi((char*)result.columns.price.c_str()) - step);
					}
				}
				else if(!strcmp("rrp",(char*)column_start_from.c_str())){
					if(result.columns.rrp.length()>0){
						if(!strcmp("+",sign))
							col=to_string(atoi((char*)result.columns.rrp.c_str()) + step);
						else if(!strcmp("-",sign))
							col=to_string(atoi((char*)result.columns.rrp.c_str()) - step);
					}
				}
			}
		}
	}
	return col;
}


vector<string> explode(const string& str, const char& ch) {
    string next;
    vector<string> result;

    // For each character in the string
    for (string::const_iterator it = str.begin(); it != str.end(); it++) {
        // If we've hit the terminal character
        if (*it == ch) {
            // If we have some characters accumulated
            if (!next.empty()) {
                // Add them to the result vector
                result.push_back(next);
                next.clear();
            }
        } else {
            // Accumulate the next character into the sequence
            next += *it;
        }
    }
    if (!next.empty())
         result.push_back(next);
    return result;
}

void processFile(string filename, int id_supplier)
{
	if(id_supplier == 0)
		return;
	ifstream in(filename.c_str());
	string line;
	while(getline(in, line))
		processLine(line);
}

sql::ResultSet *db_get(char* query){
	sql::Driver *driver;
	sql::Connection *con;
	sql::Statement *stmt;
	sql::ResultSet *res;

	// Create a connection
	driver = get_driver_instance();
	con = driver->connect("tcp://127.0.0.1:3306", "root", "1");
	// Connect to the MySQL test database
	con->setSchema("markrt");
	stmt = con->createStatement();
	res = stmt->executeQuery(query);
	delete stmt;
	delete con;
	return res;
}

int makeChecks()
{
	setlocale(LC_ALL, "");
	//if(setlocale(LC_ALL, 0) == "C") {
	//	return 4;
	//}
	return 0;
}

bool reg1(char value[],char pattern[]){
	string patt,val;
	patt=tolower(string(pattern));
	val=tolower(string(value));

	const unsigned char *tables = NULL;
	setlocale (LC_CTYPE, (const char *) "ru.");
	tables = pcre_maketables();
	pcre *re;
	int options = 0;
	const char *error;
	int erroffset;
	re  =  pcre_compile ((char *) patt.c_str(), options, &error, &erroffset, NULL);
	if (re<0){
		return false;
	}
	else{
		int count = 0;
		int ovector[30];
		count  =  pcre_exec(re,  NULL, (char *) val.c_str(), val.length(), 0, 0, ovector, 30);
		if (!count){
			return false;
		}
		else{
			for (int c = 0; c < 2 * count; c += 2){
				if (ovector[c] < 0){
					return false;
				}
				else{
					return true;
				}
			}
		}
	}
	return false;
}

Result checkPricelistTemplate(string filename){
	map <string,string> errors;
	errors["101"]='Не найдены все колонки для указанного типа заливки : название';
	errors["102"]='Не найдены все колонки для указанного типа заливки : название и/или артикул';
	errors["103"]='Не найдены все колонки для указанного типа заливки : название и/или код';
	errors["104"]='Не найдены все колонки для указанного типа заливки : артикул';
	errors["105"]='Не найдены все колонки для указанного типа заливки : код';
	errors["106"]='Не найдены все колонки для указанного типа заливки : все';
	errors["2"]='Не указан тип заливки';
	errors["3"]='Неверные параметры метода';
	errors["4"]='Не поддерживается ни одна из перечисленных локалей (ru_RU.utf8, en_US.utf8)';
	errors["5"]='Тип файла дожлен быть CSV';
	errors["6"]='Не найден файл в спике';
	int i;
	char* line_arr;
	int row,column;
	sql::ResultSet *res;
	res=db_get("SELECT pricelists_templates FROM user WHERE id='3344'");
	struct Result result;
	while (res->next()) {
		vector<JsonDataModel> models1 = getJsonDataModelFromString(tochar(res->getString("pricelists_templates")));
		for(int i = 0; i < models1.size(); i++){
			models1[i].settings.file_name=str_replace("\"", "", models1[i].settings.file_name);
			if(preg_match(models1[i].settings.file_name,filename).size()>0){
				result.settings=models1[i].settings;
				result.service_marks=models1[i].service_marks;
				result.custom_values=models1[i].custom_values;
				ifstream in(filename.c_str());
				string line;
				row=0;
				result.start_line=-1;
				while(getline(in, line)){
					row++;
					line=str_replace("\"","",line);
					//cout<<line<<endl;
					line=str_replace(",,",", ,",line);
					//cout<<line<<endl;
					line_arr = strtok(tochar(line), ",");
					column=-1;
					while(line_arr){
						line_arr=tochar(alfanumericallowedonly(string(line_arr)));
						//cout << line_arr << endl;
						column++;
						if(models1[i].columns.name.length()>0 && preg_match(models1[i].columns.name,string(line_arr)).size()>0 && !strcmp("",tochar(result.columns.name))){
							if(result.start_line!=-1){
								result.start_line = row+1;
							}
							result.columns.name = to_string(column);
						}
						if(models1[i].columns.article.length()>0 && preg_match(models1[i].columns.article,string(line_arr)).size()>0 && !strcmp("",tochar(result.columns.article))){
							if(result.start_line!=-1){
								result.start_line = row+1;
							}
							result.columns.article = to_string(column);
						}
						if(models1[i].columns.code.length()>0 && preg_match(models1[i].columns.code,string(line_arr)).size()>0 && !strcmp("",tochar(result.columns.code))){
							if(result.start_line!=-1){
								result.start_line = row+1;
							}
							result.columns.code = to_string(column);
						}
						if(models1[i].columns.price.length()>0 && preg_match(models1[i].columns.price,string(line_arr)).size()>0 && !strcmp("",tochar(result.columns.price))){
							if(result.start_line!=-1){
								result.start_line = row+1;
							}
							result.columns.price = to_string(column);
							result.settings.price_zero = models1[i].settings.price_zero;
						}
						if(models1[i].columns.rrp.length()>0 && preg_match(models1[i].columns.rrp,string(line_arr)).size()>0 && !strcmp("",tochar(result.columns.rrp))){
							if(result.start_line!=-1){
								result.start_line = row+1;
							}
							result.columns.rrp = to_string(column);
							result.settings.rrp_zero = models1[i].settings.price_zero;
						}
						if(models1[i].columns.comment.length()>0 && preg_match(models1[i].columns.comment,string(line_arr)).size()>0 && !strcmp("",tochar(result.columns.comment))){
							if(result.start_line!=-1){
								result.start_line = row+1;
							}
							result.columns.comment = to_string(column);
						}
						if(models1[i].columns.quantity.size()>0){
							for(int k=0;k<models1[i].columns.quantity.size();k++){
								if(models1[i].columns.quantity[k].length()>0 && preg_match(models1[i].columns.quantity[k],string(line_arr)).size()>0 && !strcmp("",tochar(result.columns.quantity[k]))){
									if(result.start_line!=-1){
										result.start_line = row+1;
									}
									result.columns.quantity[k] = to_string(column);
									result.settings.quantity_zero = models1[i].settings.quantity_zero;
								}
							}
						}
						if(models1[i].columns.more_comment.size()>0){
							for(int k=0;k<sizeof(models1[i].columns.more_comment);k++){
								if(models1[i].columns.more_comment[k].length()>0 && preg_match(models1[i].columns.more_comment[k],line_arr).size()>0 && strcmp("",tochar(result.columns.more_comment[k]))){
									if(result.start_line!=-1){
										result.start_line = row+1;
									}
									result.columns.more_comment[k] = to_string(column);
								}
							}
						}
						line_arr = strtok(NULL, ",");
					}
				}
				cout<<3<<endl;
				if(models1[i].relative_columns.name.length()>0){
					result.columns.name=relative_str(result,result.columns.name,result.relative_columns.name);
					result.columns.article=relative_str(result,result.columns.article,result.relative_columns.article);
					result.columns.code=relative_str(result,result.columns.code,result.relative_columns.code);
					result.columns.price=relative_str(result,result.columns.price,result.relative_columns.price);
					result.columns.rrp=relative_str(result,result.columns.rrp,result.relative_columns.rrp);

					for(int z=0;z<models1[i].relative_columns.quantity.size();z++)
						result.columns.quantity[z]=relative_str(result,result.columns.quantity[z],result.relative_columns.quantity[z]);
					for(int z=0;z<models1[i].relative_columns.more_comment.size();z++)
						result.columns.more_comment[z]=relative_str(result,result.columns.more_comment[z],result.relative_columns.more_comment[z]);
				}

				if(!strcmp("name",tochar(result.settings.merge_type)) || !strcmp("name_comment",tochar(result.settings.merge_type))){
					if(result.columns.name.length()<=0 || (result.columns.price.length()<=0 && result.columns.rrp.length()<=0 && result.columns.quantity.size()<=0)){
						result.error = "101";
					}
				}
				else if(!strcmp("name_article",tochar(result.settings.merge_type)) || !strcmp("name_article_comment",tochar(result.settings.merge_type))){
					if(result.columns.name.length()<=0 || result.columns.article.length()<=0 || (result.columns.price.length()<=0 && result.columns.rrp.length()<=0 && result.columns.quantity.size()<=0)){
						result.error = "102";
					}
				}
				else if(!strcmp("name_code",tochar(result.settings.merge_type))){
					if(result.columns.name.length()<=0 || result.columns.code.length()<=0 || (result.columns.price.length()<=0 && result.columns.rrp.length()<=0 && result.columns.quantity.size()<=0)){
						result.error = "103";
					}
				}
				else if(!strcmp("article",tochar(result.settings.merge_type)) || !strcmp("article_comment",tochar(result.settings.merge_type))){
					if(result.columns.article.length()<=0 || result.columns.comment.length()<=0 || (result.columns.price.length()<=0 && result.columns.rrp.length()<=0 && result.columns.quantity.size()<=0)){
						result.error = "104";
					}
				}
				else if(!strcmp("code",tochar(result.settings.merge_type))){
					if(result.columns.code.length()<=0 || (result.columns.price.length()<=0 && result.columns.rrp.length()<=0 && result.columns.quantity.size()<=0)){
						result.error = "105";
					}
				}
				else if(!strcmp("all",tochar(result.settings.merge_type))){
					if(result.columns.name.length()<=0 || result.columns.article.length()<=0 || result.columns.code.length()<=0 || (result.columns.price.length()<=0 && result.columns.rrp.length()<=0 && result.columns.quantity.size()<=0)){
						result.error = "106";
					}
				}
				else if(!strcmp("article_code",tochar(result.settings.merge_type))){
					if(result.columns.article.length()<=0 || result.columns.code.length()<=0 || (result.columns.price.length()<=0 && result.columns.rrp.length()<=0 && result.columns.quantity.size()<=0)){
						result.error = "107";
					}
				}
				else
					result.error="2";
				if(result.error.length()==0)
					break;
				else
					result.error_rus=errors[result.error];
			}
		}
	}
	return result;
}

void get_new_csv(string column, map<string, string> &csv, string csv_name)
{
	vector<string> matches;
	string column_name;
	trim(column);
	matches=relative_reg(".+", column);

	if(matches[0].length() > 0) {
		column_name = matches[0] + "_csv";
		if(!csv[column_name].length()) {
			csv[column_name] = to_string(0);
		}
		if(matches[1] == "+") {
			csv[csv_name] = to_string(toint(csv[column_name]) + toint(matches[2]));
		} else if(matches[1] == "-") {
			csv[csv_name] = to_string(toint(csv[column_name]) - toint(matches[2]));
		} else if(matches[1] == "*") {
			csv[csv_name] = to_string(toint(csv[column_name]) * toint(matches[2]));
		} else if(matches[1] == "/") {
			ostringstream ss;
			ss << (float)((float)toint(csv[column_name]) / (float)toint(matches[2]));
			csv[csv_name] = ss.str();
		} else if(matches[1] == ".") {
			csv[csv_name] = csv[column_name] + "." + matches[2];
		}
	}
}

int continuePricelistString()
{
	int continue_ = 0;
	int empty_data = 0;
	bool data_can_be_empty = true;

	int empty_data_total_conditions = 3;
	int empty_data_true_conditions = 0;

	map<string, string> tmp_csv = csv_data;
	
	string merge_type = pricelist_config.settings.merge_type;
	
	vector<string> target_field_name;
	vector<string> target_field_csv;
	
	for(int k = 0; k < service_mode.size(); k++) {
		if(service_mode[k] == 4) {
			string pricelist_settings_service_mark_target_value = pricelist_config.service_marks[k].main["target"];
			if(pricelist_settings_service_mark_target_value.length() == 0) {
				pricelist_settings_service_mark_target_value = pricelist_config.service_marks[k].main["source"];
				if(pricelist_settings_service_mark_target_value.length() == 0) {
					pricelist_settings_service_mark_target_value = "name";
				}
			}
			target_field_name.push_back(pricelist_settings_service_mark_target_value + "_csv");
			target_field_name.push_back(prev_name[k] + " " + csv[target_field_name[k]]);
		}
	}
	
	if(pricelist_config.settings.price_zero.length() > 0) {
		empty_data_total_conditions--;
		if(pricelist_config.columns.price.length() > 0) {
			data_can_be_empty = false;
		}
	} else {
		if(1/* array search  != false*/) {
			int key = 0;// array search
			if(target_field_csv[key] == "") {
				empty_data_true_conditions++;
			}
		} else if(csv["price_csv"] == "") {
			empty_data_true_conditions++;
		}
	}
	
	if(pricelist_config.settings.quantity_zero.length() > 0) {
		empty_data_total_conditions--;
		if(pricelist_config.columns.quantity.size() > 0) {
			data_can_be_empty = false;
		}
	} else {
		if(1/* array search*/) {
			int key = 1;// array_search
			if(target_field_csv[key] == "") {
				empty_data_true_conditions++;
			}
		} else if(csv["quantity_csv"] == "") {
			empty_data_true_conditions++;
		}
	}

	if(pricelist_config.settings.rrp_zero.length() > 0) {
		empty_data_total_conditions--;
		if(pricelist_config.columns.rrp.length() > 0){
			data_can_be_empty = false;
		}
	} else {
		if(1/* array search != false*/) {
			int key = 0;// array seaech
			if(target_field_csv[key] == "") {
				empty_data_true_conditions++;
			}
		}
		else if(csv["rrp_csv"] == "") {
			empty_data_true_conditions++;
		}
	}

	if(empty_data_true_conditions == empty_data_total_conditions && data_can_be_empty) {
		empty_data = 1;
	}

	if(empty_data) {
		continue_ = 1;
	} else if(1 /* in array name name_comment*/) {
		if(1 /* as name_csv tfn*/) {
			int key = 0; // as
			if(target_field_csv[key] == "") {
				continue_ = 1;
			}
		}
	} else if(1 /*in array*/) {
		if(1 /*array search name_csv*/) {
			int key = 1;// array search
			if(target_field_csv[key] == "") {
				continue_ = 1;
			}
		} else if(1 /*as article_csv*/) {
			int key = 0;// as articls_csv
			if(target_field_csv[key] == "") {
				continue_ = 1;
			}
		} else {
			if(csv["name_csv"] == "" && csv["article_csv"] == "") {
				continue_ = 1;
			}
		}
	} else if(1 /*ia name_code*/) {
		if(1 /*as  name_csv*/) {
			int key = 1; //as nmae_csv
			if(target_field_csv[key] == "") {
				continue_ = 1;
			}
		} else if(1 /*as code_csv*/) {
			int key = 0; //as code
			if(target_field_csv[key] == "") {
				continue_ = 1;
			}
		} else {
			if(csv["name_csv"] == "" && csv["code_csv"] == "") {
				continue_ = 1;
			}
		}
	}
	else if(1 /*in array article_code*/) {
		if(1 /*as article_csv*/) {
			int key = 0; //as article
			if(target_field_csv[key] == "") {
				continue_ = 1;
			}
		} else if(1 /*as code*/) {
			int key = 0; //as code
			if(target_field_csv[key] == ""){
				continue_ = 1;
			}
		} else {
			if(csv["article_csv"] == "" && csv["code_csv"] == "") {
				continue_ = 1;
			}
		}
	}
	else if(1 /*ia article comment*/) {
		if(1 /*as article_csv*/) {
			int key = 0; //as article_csv
			if(target_field_csv[key] == ""){
				continue_ = 1;
			}
		}
	}
	else if(1 /*in array code*/) {
		if(1 /*as code_csv*/) {
			int key = 0; //as code_csv
			if(target_field_csv[key] == ""){
				continue_ = 1;
			}
		}
	} else if(1 /* ia all*/) {
		if(csv["name_csv"] == "" && csv["article_csv"].length() > 0 && csv["code_csv"].length() > 0) {
			continue_ = 1;
		}
	}
	else {
		continue_ = 2;
	}
	return continue_;
}

void serviceMarkSettingsProcessing(int i, bool from_five_to_four)
{
	for(int k = 0; k < service_mark_settings.size(); k++) {

		string new_name;
		int p_tmp_first_index;
		int continue_ = 0;
		vector<map<string, string>> pricelist_tmp_tmp;

		if(csv["service_mark_csv"] == "4" && service_mode[k] != 4) {
			pricelist_tmp[k].empty();
			pricelist_tmp[k][i]["first"] = "1";
			service_mode[k] = 4;
			prev_name[k] = prev_field[k];
			prev_name_replaced[k] = prev_field_replaced[k];
			start_collecting_four[k] = true;
		}

		if(service_mode[k] == toint("4") && start_collecting_four[k]) {
			if(csv["service_mark_csv"].length() > 0) {
				if(service_mark_settings[k]["four_type"] == "2") {
					new_name = "";
					p_tmp_first_index = 0;
					for(int p_tmp_index = 0; p_tmp_index < pricelist_tmp[k].size(); p_tmp_index++) {
						if(!p_tmp_first_index) {
							p_tmp_first_index = p_tmp_index;
						}
						new_name += " " + pricelist_tmp[k][p_tmp_index]["name"];
					}
					trim(new_name);
					vector<map<string, string>> new_pricelist_tmp;
					new_pricelist_tmp.push_back(pricelist_tmp[k][p_tmp_first_index]);
					new_pricelist_tmp[p_tmp_first_index]["name"] = new_name;
					new_pricelist_tmp[p_tmp_first_index]["first"] = "";
					pricelist_tmp[k] = new_pricelist_tmp;

					csv_data.empty();
					csv_data["price_csv"] = pricelist_tmp[k][p_tmp_first_index]["price"];
					csv_data["quantity_csv"] = pricelist_tmp[k][p_tmp_first_index]["quantity"];
					csv_data["rrp_csv"] = pricelist_tmp[k][p_tmp_first_index]["rrp"];
					csv_data["name_csv"] = pricelist_tmp[k][p_tmp_first_index]["name"];
					csv_data["article_csv"] = pricelist_tmp[k][p_tmp_first_index]["article"];
					csv_data["code_csv"] = pricelist_tmp[k][p_tmp_first_index]["code"];
					csv_data["comment_csv"] = pricelist_tmp[k][p_tmp_first_index]["comment"];

					continue_ = continuePricelistString();

					/*
					for()
					*/
					line_of_text.empty();
					line_of_text.push_back(pricelist_config.columns.name);
					line_of_text.push_back(pricelist_config.columns.article);
					line_of_text.push_back(pricelist_config.columns.code);
					line_of_text.push_back(pricelist_config.columns.price);
					for(int j = 0; j < pricelist_config.columns.quantity.size(); j++) {
						line_of_text.push_back(pricelist_config.columns.quantity[j]);
					}
					line_of_text.push_back(pricelist_config.columns.rrp);
					line_of_text.push_back(pricelist_config.columns.comment);
					for(int j = 0; j < pricelist_config.columns.more_comment.size(); j++) {
						line_of_text.push_back(pricelist_config.columns.more_comment[j]);
					}
				}
				else {
					for(int p_tmp_index = 0; p_tmp_index < pricelist_tmp[k].size(); p_tmp_index++) {
						if(service_mark_settings[k]["get_first"].length() > 0) {
							if(pricelist_tmp[k].size() > 1 && pricelist_tmp[k][p_tmp_index]["first"].length() > 0) {
								pricelist_tmp[k][p_tmp_index].empty();
							}
						}
						if((pricelist_tmp[k][p_tmp_index]["first"].length() > 0 && 
								service_mark_settings[k]["get_first"].length() > 0) || 
								pricelist_tmp[k][p_tmp_index]["first"].length() == 0) {
							if(service_mark_settings[k]["target"] == "name") {
								pricelist_tmp[k][p_tmp_index]["name_original"] = pricelist_tmp[k][p_tmp_index]["name"];
								pricelist[p_tmp_index]["name_original"] = "";
							}
							string target = service_mark_settings[k]["target"];
							string target_replaced_field;

							map<string, string> tmap;
							pricelist_tmp_tmp.push_back(tmap);
							if(target == "price" || target == "quantity" || target == "rrp") {
								pricelist_tmp_tmp[p_tmp_index]["target"] = prev_name[k];
							} else {
								pricelist_tmp_tmp[p_tmp_index]["target"] = prev_name[k] + " " + pricelist_tmp[k][p_tmp_index]["target"];
							}
							if(target == "name" || target == "article" || target == "code") {
								target_replaced_field = target + "_replaced";
								pricelist_tmp_tmp[p_tmp_index][target_replaced_field] = "";//tolower() ???
							}
							//for(/*array keys*/) {};

						}
						if(pricelist_tmp[k][p_tmp_index]["first"].length() > 0) {
							pricelist_tmp[k][p_tmp_index]["first"] = "";
						}
					}
					if(pricelist_tmp[k].size() > 0) {
						pricelist_tmp[k].empty();
					}
				}
				if(!continue_) {
					if(pricelist_tmp_tmp.size() > 0) {
						for(int ind = 0; ind < pricelist_tmp_tmp.size(); ind++) {
							for(map<string, string>::iterator it = pricelist_tmp_tmp[ind].begin(); 
									it != pricelist_tmp_tmp[ind].end(); it++) {
								pricelist[ind][it->first] = it->second;
							}
						}
						pricelist_tmp_tmp.empty();
					}
					if(pricelist_tmp[k].size() > 0) {
						for(int ind = 0; ind < pricelist_tmp[k].size(); ind++) {
							for(map<string, string>::iterator it = pricelist_tmp[k][ind].begin(); 
									it != pricelist_tmp[k][ind].end(); it++) {
								pricelist[ind][it->first] = it->second;
							}
						}
						pricelist_tmp[k].empty();
					}
				}

				if(csv["service_mark_csv"] != "5" || from_five_to_four) {
					service_mode[k] = 0;
					pricelist_tmp[k].empty();
				}
				if(csv["service_mark_csv"] == "4") {
					pricelist_tmp[k][i]["first"] = "1";
					service_mode[k] = 4;
					prev_name[k] == prev_field[k];
					prev_name_replaced[k] = prev_field_replaced[k];
					start_collecting_four[k] = true;
				}
			}
		}
	}
}

int uploadPricelist(string file, int id, string filename, vector<string> user_config)
{
	vector<string> cmatch;
	cmatch=relative_reg("([a-z]+|[+-]|[0-9]+)","article -   5");
	//cout<<cmatch[0]<<endl<<cmatch[1]<<endl<<cmatch[2]<<endl;

	int i,total_strings = 0,row;
	//map<string, string> csv; global
	int quantity_csv=-1;
	vector<string> more_comment_csv1, matches;

	vector<string> line_csv;
	// Result pricelist_config // global
	pricelist_config = checkPricelistTemplate(filename);
	Result result;
	if(pricelist_config.error.length()==0){
		result.error=pricelist_config.error;
		return 0;
	}
	if(pricelist_config.settings.merge_type.length()>0 && pricelist_config.settings.merge_type != "none"){
		i = -1;
		ifstream in(filename.c_str());
		string line;
		row=0;
		char* line_arr;
		while(getline(in, line)){
			row++;
			if(pricelist_config.start_line && row<pricelist_config.start_line)
				continue;
			total_strings++;
			csv["name_csv"] = "";
			csv["name_csv_replaced"] = "";
			csv["article_csv"] = "";
			csv["article_csv_replaced"] = "";
			csv["code_csv"] = "";
			csv["code_csv_replaced"] = "";
			csv["price_csv"] = "";
			quantity_csv = -1;
			csv["rrp_csv"] = "";
			csv["comment_csv"] = "";
			csv["comment_csv_replaced"] = "";
			csv["service_mark_csv"] = "";

			line=str_replace("\"","",line);
			line_arr = strtok((char*)line.c_str(), ",");

			while(line_arr){
				line_arr = strtok(NULL, ",");
				line_csv.push_back(string(line_arr));
			}
			if(pricelist_config.columns.name.length()>0 && line_csv[toint(pricelist_config.columns.name)]!=""){
				csv["name_csv"] = line_csv[toint(pricelist_config.columns.name)];
				trim(csv["name_csv"]);
				csv["name_csv"] = csv["name_csv"].substr(0,500);
				csv["name_csv_replaced"] = tolower(csv["name_csv"]);
				if(pricelist_config.settings.name_out_of_stock.length()>0){
					if(reg1(tochar(pricelist_config.settings.name_out_of_stock),tochar(line_csv[toint(pricelist_config.columns.name)]))){
						if(quantity_csv == -1){
							quantity_csv = 0;
						}
						csv["name_csv"] = p_replace(pricelist_config.settings.name_out_of_stock,"",csv["name_csv"]);
						csv["name_csv"] = csv["name_csv"].substr(0,500);
						csv["name_csv_replaced"] = tolower(csv["name_csv"]);
					}
					else
						quantity_csv=1;
				}
			}
			if(pricelist_config.columns.article.length()>0 && line_csv[toint(pricelist_config.columns.article)]!=""){
				csv["article_csv"] = line_csv[toint(pricelist_config.columns.article)];
				trim(csv["article_csv"]);
				csv["article_csv"] = csv["article_csv"].substr(0,500);
				csv["article_csv_replaced"] = tolower(csv["article_csv"]);
			}
			if(pricelist_config.columns.code.length()>0 && line_csv[toint(pricelist_config.columns.code)]!=""){
				csv["code_csv"] = line_csv[toint(pricelist_config.columns.code)];
				trim(csv["code_csv"]);
				csv["code_csv"] = csv["code_csv"].substr(0,500);
				csv["code_csv_replaced"] = tolower(csv["code_csv"]);
			}
			if(pricelist_config.columns.price.length()>0 && line_csv[toint(pricelist_config.columns.price)]!=""){
				csv["price_csv"] = line_csv[toint(pricelist_config.columns.price)];
			}
			if(pricelist_config.columns.quantity.size()>0){
				for(int z=0;z<=pricelist_config.columns.quantity.size();z++){
					if(pricelist_config.settings.quantity_in_stock.length()>0 && 
					reg1(tochar(pricelist_config.settings.quantity_in_stock),tochar(line_csv[toint(pricelist_config.columns.quantity[z])]))) {
						quantity_csv++;
					}
					else if(pricelist_config.settings.quantity_out_of_stock.length()>0 && 
					reg1(tochar(pricelist_config.settings.quantity_out_of_stock),tochar(line_csv[toint(pricelist_config.columns.quantity[z])]))){
						if(quantity_csv == -1)
							quantity_csv = 0;
					}
					else{
						matches=relative_reg("+",line_csv[toint(pricelist_config.columns.quantity[z])]);
						if(matches.size()>0){
							quantity_csv += atoi(tochar(matches[0]));
							if(atoi(tochar(matches[0]))<0 && quantity_csv==-1){
								quantity_csv=0;
							}
						}
					}
				}
			}
			if(pricelist_config.columns.rrp.length() > 0 && line_csv[toint(pricelist_config.columns.rrp)] != ""){
				csv["rrp_csv"] = line_csv[toint(pricelist_config.columns.rrp)];
			}
			if(pricelist_config.columns.comment.length()>0 && line_csv[toint(pricelist_config.columns.comment)] != ""){
				csv["comment_csv"] = line_csv[toint(pricelist_config.columns.comment)];
				trim(csv["comment_csv"]);
				csv["comment_csv"] = csv["comment_csv"].substr(0,500);
				csv["comment_csv_replaced"] = tolower(csv["comment_csv"]);
			}
			if(pricelist_config.columns.more_comment.size()>0){
				for(int z = 0;z <= pricelist_config.columns.more_comment.size(); z++){
					more_comment_csv1.push_back(line_csv[toint(pricelist_config.columns.more_comment[z])]);
					trim(more_comment_csv1[z]);
					more_comment_csv1.push_back(more_comment_csv1[z].substr(0,500));
				}
				csv["more_comment_csv"] = implode("_",more_comment_csv1);
				csv["comment_csv"] = csv["comment_csv"] + "_" + csv["more_comment_csv"];
				csv["comment_csv_replaced"] = tolower(csv["comment_csv"]);
			}


			//custom value process
			if(pricelist_config.custom_values.name.length() > 0) {
				get_new_csv(pricelist_config.custom_values.name, csv, "name_csv");
			}
			if(pricelist_config.custom_values.article.length() > 0) {
				get_new_csv(pricelist_config.custom_values.article, csv, "article_csv");
			}
			if(pricelist_config.custom_values.code.length() > 0) {
				get_new_csv(pricelist_config.custom_values.code, csv, "code_csv");
			}
			if(pricelist_config.custom_values.price.length() > 0) {
				get_new_csv(pricelist_config.custom_values.price, csv, "price_csv");
			}
			if(pricelist_config.custom_values.quantity.size() > 0) {
				get_new_csv(pricelist_config.custom_values.quantity, csv, "quantity_csv");
			}
			if(pricelist_config.custom_values.rrp.length() > 0) {
				get_new_csv(pricelist_config.custom_values.rrp, csv, "rrp_csv");
			}
			if(pricelist_config.custom_values.comment.length() > 0) {
				get_new_csv(pricelist_config.custom_values.comment, csv, "comment_csv");
			}
				// service mark process
			map<string, string> service_mark_tmp;
			// vector<map<string, string>> service_mark_settings; global
			for(int index = 0; index < pricelist_config.service_marks.size(); index++) {
				int true_conditions = 0;
				int total_conditions = 0;
				string source = "";
				string target = "";
				string get_first = "";
				string column_name;
				for(map<string, string>::iterator it = pricelist_config.service_marks[index].main.begin();
						it != pricelist_config.service_marks[index].main.end(); ++it) {
					if(it->first == "type") {
						service_mark_tmp["service_mark_four_type"] = it->second;
					} else if(it->first == "source") {
						service_mark_tmp["service_mark_source_tmp"] = it->second;
					} else if(it->first == "target") {
						service_mark_tmp["service_mark_target_tmp"] = it->second;
					} else if(it->first == "get_first") {
						get_first = it->second;
					} else {
						total_conditions++;
						column_name = it->first + "_csv";
						if(1/*preg_match("", "", csv[column_name])*/) {
							true_conditions++;
							}
						}
					}
					if(true_conditions == total_conditions && total_conditions > 0) {
						if(service_mark_tmp["service_mark_source_tmp"].length() > 0) {
							source = service_mark_tmp["service_mark_source_tmp"];
						} else {
							source = "name";
						}
						if(service_mark_tmp["service_mark_target_tmp"].length() > 0) {
							target = service_mark_tmp["service_mark_target_tmp"];
						} else {
							target = source;
						}
						csv["service_mark_csv"] = "4";
						map<string, string> sms;
						sms["four_type"] = service_mark_tmp["service_mark_four_type"];
						sms["source"] = source;
						sms["target"] = target;
						sms["get_first"] = get_first;
						service_mark_settings.push_back(sms);
						/// ????
					} else if(/* ?? service mode ?? */ pricelist_config.service_marks[index].extention.size() > 0) {
						true_conditions = 0;
						total_conditions = 0;
						for(map<string, string>::iterator it = pricelist_config.service_marks[index].main.begin();
							it != pricelist_config.service_marks[index].main.end(); ++it) {
								total_conditions++;
							column_name = it->first + "_csv";
							if(1/*preg_match(), csv[column_name]*/) {
								true_conditions++;
							}
						}
						if(true_conditions == total_conditions && total_conditions > 0) {
							if(service_mark_tmp["service_mark_source_tmp"].length() > 0) {
								source = service_mark_tmp["service_mark_source_tmp"];
							} else {
								source = "name";
							}
							if(service_mark_tmp["service_mark_target_tmp"].length()) {
								target = service_mark_tmp["service_mark_target_tmp"];
							} else {
								target = source;
							}
							csv["service_mark_csv"] = "5";
							map<string, string> sms;
							sms["four_type"] = service_mark_tmp["service_mark_four_type"];
							sms["source"] = source;
							sms["target"] = target;
							// sms["get_first"] = get_first;
							service_mark_settings.push_back(sms);
						}
					}
				}
				// end service mark process
				// array decl
				vector<string> prev_field;
				vector<string> prev_field_replaced;
				vector<string> service_mark_settings_four_type_array;
				for(int k = 0; k < service_mark_settings.size(); k++) {
					string prev_field_name = service_mark_settings[k]["source"] + "_csv";
					prev_field.push_back(csv[prev_field_name]);
					service_mark_settings_four_type_array.push_back(service_mark_settings[k]["four_type"]);
				}
				// map<string, string> csv_data; // is global
				csv_data["price_csv"] = csv["price_csv"];
				csv_data["quantity_csv"] = to_string(quantity_csv);
				csv_data["rrp_csv"] = csv["rrp_csv"];
				csv_data["name_csv"] = csv["name_csv"];
				csv_data["code_csv"] = csv["code_csv"];
				csv_data["comment_csv"] = csv["comment_csv"];
				int continue_ = 0;

				if(csv["service_mark_csv"] == "0") {
					continue;
				}
				// start_collecting_four array?

				if(service_mark_settings.size() > 0) {
					// serviceMarkSettingsProcessing(i)
				}

				if(1 /*in array*/) {
					continue_ = 1/*continuePricelistString()*/;
				}

				if(!continue_ /* what ??*/) {
					result.error = continue_;
					// return;??
				}
				if(continue_) {
					continue;
				}

				bool sm_true = true;
				if(strcmp("",tochar(csv["name_csv"]))){
					sm_true = false;
					for(int z = 0;z < service_mode.size(); z++){
						if(service_mode[z]>0){
							sm_true=true;
							pricelist_tmp[z][i]["name"] = csv["name_csv"];
							pricelist_tmp[z][i]["name_replaced"] = csv["name_csv_replaced"];
						}
					}
					if(sm_true == false){
						pricelist[i]["name"] = csv["name_csv"];
						pricelist[i]["name_replaced"] = csv["name_csv_replaced"];
					}
				}
				if(strcmp("",tochar(csv["article_csv"]))){
					sm_true = false;
					for(int z = 0;z < service_mode.size(); z++){
						if(service_mode[z] > 0){
							sm_true = true;
							pricelist_tmp[z][i]["article"] = csv["article_csv"];
							pricelist_tmp[z][i]["article_replaced"] = csv["article_csv_replaced"];
						}
					}
					if(sm_true == false){
						pricelist[i]["article"] = csv["article_csv"];
						pricelist[i]["article_replaced"] = csv["article_csv_replaced"];
					}
				}

				if(strcmp("",tochar(csv["code_csv"]))){
					sm_true = false;
					for(int z = 0; z < service_mode.size(); z++){
						if(service_mode[z]>0){
							sm_true=true;
							pricelist_tmp[z][i]["code"] = csv["code_csv"];
							pricelist_tmp[z][i]["code_replaced"] = csv["code_csv_replaced"];
						}
					}
					if(sm_true == false){
						pricelist[i]["code"] = csv["code_csv"];
						pricelist[i]["code_replaced"] = csv["code_csv_replaced"];
					}
				}
				if(strcmp("",tochar(csv["price_csv"]))){
					sm_true = false;
					for(int z = 0; z < service_mode.size() ; z++){
						if(service_mode[z]>0){
							sm_true=true;
							pricelist_tmp[z][i]["price"]= csv["price_csv"];
						}
					}
					if(sm_true == false){
						pricelist[i]["price"] = csv["price_csv"];
					}
				}

				if(strcmp("",tochar(csv["quantity_csv"]))){
					sm_true = false;
					for(int z = 0; z < service_mode.size() ; z++){
						if(service_mode[z]>0){
							sm_true=true;
							pricelist_tmp[z][i]["quantity"]= csv["quantity_csv"];
						}
					}
					if(sm_true == false){
						pricelist[i]["quantity"] = csv["quantity_csv"];
					}
				}

				if(strcmp("",tochar(csv["rrp_csv"]))){
					sm_true = false;
					for(int z = 0; z < service_mode.size() ; z++){
						if(service_mode[z]>0){
							sm_true=true;
							pricelist_tmp[z][i]["rrp"]= csv["rrp_csv"];
						}
					}
					if(sm_true == false){
						pricelist[i]["rrp"] = csv["rrp_csv"];
					}
				}

				if(strcmp("",tochar(csv["comment_csv"]))){
					sm_true = false;
					for(int z = 0; z < service_mode.size(); z++){
						if(service_mode[z]>0){
							sm_true=true;
							pricelist_tmp[z][i]["comment"] = csv["comment_csv"];
							pricelist_tmp[z][i]["comment_replaced"] = csv["comment_csv_replaced"];
						}
					}
					if(sm_true == false){
						pricelist[i]["comment"] = csv["comment_csv"];
						pricelist[i]["comment_replaced"] = csv["comment_csv_replaced"];
					}
				}

				if(csv["service_mark_csv"] == "5") {
					serviceMarkSettingsProcessing(i, true);
				}

//				if(1 /*service_mode != "4" it is an array !!! */) {
//					if(csv["service_mark_csv"] == "1") {
//						pricelist_tmp.empty();
//						//service_mode = 1; array !!!
//						prev_name = prev_field;
//						prev_name_replaced = prev_field_replaced;
//					}
//					else if(csv["service_mark_csv"] == "2" /* && service_mode  array !!!*/) {
//						for(int j = 0; j < pricelist_tmp[i].size(); j++) {
//							pricelist_tmp[i][j]["comment"] = prev_name;
//							pricelist_tmp[i][j]["comment_replaced"] = prev_name_replaced;
//						}
//						// pricelist = array_merge ??
//						// service_mode = 1 ??? ARRAY !!!
//						pricelist_tmp[i].empty();
//					}
//					else if(csv["service_mark_csv"] == "3" /* && service_mode array !!! */) {
//						for(int j = 0; j < pricelist_tmp[i].size(); j++) {
//							pricelist_tmp[i][j]["name_original"] = pricelist_tmp[i][j]["name"];
//							pricelist_tmp[i][j]["name"] = prev_name + " " + pricelist_tmp[i][j]["name"];
//						}
//						// pricelist = array_merge ??
//						// service_mode = 0 ??? ARRAY !!!
//						pricelist_tmp[i].empty();
//					}
//					else {
//						sm_true = false;
//						for(int j = 0; j < service_mode.size(); j++) {
//							if(service_mode[j]) {
//								prev_name[j] = prev_field[j];
//								prev_name_replaced[j] = prev_field_replaced[j];
//							}
//						}
//					}
//				}

				vector<map<string, string>> service_mark_settings_l;
				for(int sm_index = 0; sm_index < pricelist_config.service_marks.size(); sm_index++) {
					string source = "";
					string target = "";
					string get_first = "";
					if(pricelist_config.service_marks[sm_index].main.size() > 0) {
						for(map<string, string>::iterator it = pricelist_config.service_marks[sm_index].main.begin(); 
								it != pricelist_config.service_marks[sm_index].main.end(); it++) {
							if(it->first == "type") {
								service_mark_tmp["service_mark_four_type"] = it->second;
							}
							else if(it->first == "source") {
								source = it->second;
							}
							else if(it->first == "target") {
								target = it->second;
							}
							else if(it->first == "get_first") {
								get_first = it->second;
							}
						}
						
						if(source.length() == 0) {
							source = "name";
						}
						if(target.length() == 0) {
							target = source;
						}
						
						csv["service_mark_csv"] = "4";
						service_mark_settings[sm_index]["four_type"] = service_mark_tmp["service_mark_four_type_tmp"];
						service_mark_settings[sm_index]["source"] = source;
						service_mark_settings[sm_index]["target"] = target;
						service_mark_settings[sm_index]["get_first"] = get_first;
					}
				}
			}
			serviceMarkSettingsProcessing(i);
	}
}

